////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxstatsprocessingnode.h
/// @brief Stats processing node class declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXSTATSPROCESSINGNODE_H
#define CAMXSTATSPROCESSINGNODE_H

#include "camxdefs.h"
#include "camxmem.h"
#include "camxnode.h"
#include "camxtypes.h"
#include "camxthreadmanager.h"
#include "camxstatscommon.h"
#include "camxstatsprocessormanager.h"
#include "camxmultistatsoperator.h"

CAMX_NAMESPACE_BEGIN

/// @brief Structure describing the stats job done information
struct StatsNodeJobDoneInfo
{
    UINT32          instanceId; ///< Instance Id
    StatsJobFamily  jobFamily;  ///< Job family
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Class that implements the 3A node class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class StatsProcessingNode final : public Node, public IStatsNotifier
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Static method to create StatsProcessingNode Object.
    ///
    /// @param  pCreateInputData  Node create input data
    /// @param  pCreateOutputData Node create output data
    ///
    /// @return Pointer to the concrete StatsProcessingNode object
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static StatsProcessingNode* Create(
        const NodeCreateInputData*  pCreateInputData,
        NodeCreateOutputData*       pCreateOutputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Destroy
    ///
    /// @brief  This method destroys the derived instance of the interface
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID Destroy();

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ProcessingNodeInitialize
    ///
    /// @brief  Initialize the sw processing object
    ///
    /// @param  pCreateInputData  Node create input data
    /// @param  pCreateOutputData Node create output data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ProcessingNodeInitialize(
        const NodeCreateInputData*  pCreateInputData,
        NodeCreateOutputData*       pCreateOutputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetPropertyDependencies
    ///
    /// @brief  Get the list of property dependencies from all stats processors and check if they are satisfied
    ///
    /// @param  pExecuteProcessRequestData          Pointer to Execute process request data
    /// @param  pStatsProcessRequestDataInfo        Pointer to Stats process request structure to be filled
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult GetPropertyDependencies(
        ExecuteProcessRequestData*  pExecuteProcessRequestData,
        StatsProcessRequestData*    pStatsProcessRequestDataInfo
    ) const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetBufferDependencies
    ///
    /// @brief  Checks if the buffer dependency list and check if they are satisfied
    ///
    /// @param  pExecuteProcessRequestData      Pointer to Execute process request data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult GetBufferDependencies(
        ExecuteProcessRequestData*  pExecuteProcessRequestData
    ) const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetMultiStatsDependencies
    ///
    /// @brief  Checks if the multi stats dependency list and check if they are satisfied
    ///
    /// @param  pExecuteProcessRequestData      Pointer to Execute process request data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult GetMultiStatsDependencies(
        ExecuteProcessRequestData*  pExecuteProcessRequestData
    ) const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PrepareStatsProcessRequestData
    ///
    /// @brief  Prepare data to pass to Stats ProcessRequest
    ///
    /// @param  pExecuteProcessRequestData  Pointer to Execute process request data
    /// @param  pStatsProcessRequestData    Pointer to Stats process request structure to be filled
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult PrepareStatsProcessRequestData(
        ExecuteProcessRequestData*  pExecuteProcessRequestData,
        StatsProcessRequestData*    pStatsProcessRequestData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ExecuteProcessRequest
    ///
    /// @brief  Pure virtual method to trigger process request for the stats processing node object.
    ///
    /// @param  pExecuteProcessRequestData Process request data
    ///
    /// @return CamxResultSuccess if successful and 0 dependencies, dependency information otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ExecuteProcessRequest(
        ExecuteProcessRequestData* pExecuteProcessRequestData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PostPipelineCreate
    ///
    /// @brief  virtual method to be called at NotifyTopologyCreated time; node should take care of updates and initialize
    ///         blocks that has dependency on other nodes in the topology at this time.
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult PostPipelineCreate();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// StatsProcessingNode
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    StatsProcessingNode();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~StatsProcessingNode
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~StatsProcessingNode();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief IStatsNotifier implementation
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// NotifyJobProcessRequestDone
    ///
    /// @brief  Notifies the statistic node that a job from the worker thread is completed
    ///
    /// @param  requestId   Request Id
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult NotifyJobProcessRequestDone(
        UINT64          requestId);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ProcessingNodeFinalizeInitialization
    ///
    /// @brief  Method to finalize the initialization of the node in the pipeline
    ///
    /// @param  pFinalizeInitializationData Finalize data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ProcessingNodeFinalizeInitialization(
        FinalizeInitializationData* pFinalizeInitializationData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CanSkipAlgoProcessing
    ///
    /// @brief  Decides whether we can skip algo processing for the current frame based on skip factor
    ///
    /// @param  requestId current request id
    ///
    /// @return TRUE if we can skip otherwise FALSE
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL CanSkipAlgoProcessing(
        UINT64 requestId
    ) const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetRoleName
    ///
    /// @brief  return string based on role info enum
    ///
    /// @param  role role information
    ///
    /// @return String contaning role information
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    const CHAR* GetRoleName(
        StatsAlgoRole role);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetCameraTypeName
    ///
    /// @brief  return string based on camera type enum
    ///
    /// @param  type camera type
    ///
    /// @return String contaning camera type information
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    const CHAR* GetCameraTypeName(
        StatsCameraType type);

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// InitializePreviousSessionData
    ///
    /// @brief  This function is will get the previous session data from static node.
    ///
    /// @return CamxResultSuccess if successful and 0 dependencies, dependency information otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult InitializePreviousSessionData();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// InitializeMultiStats
    ///
    /// @brief  Initialize multi camera stats operator for multi camera usecase
    ///
    /// @return CamxResultSucess if sucessful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult InitializeMultiStats();

    StatsProcessingNode(const StatsProcessingNode&)             = delete;        ///< Disallow the copy constructor.
    StatsProcessingNode& operator=(const StatsProcessingNode&)  = delete;        ///< Disallow assignment operator.

    StatsProcessorManager*      m_pStatsProcessorManager;                               ///< Pointer to stats job dispatcher
    StatsInitializeData         m_statsInitializeData;                                  ///< Save the stats settings pointer
    ChiContext*                 m_pChiContext;                                          ///< Chi context pointer
    UINT64                      m_bufferOffset;                                         ///< Offset from which to read buffers

    UINT                        m_skipPattern;                                          ///< Frames to skip
    StatsCameraInfo             m_cameraInfo;                                           ///< camera information
    MultiStatsOperator*         m_pMultiStatsOperator;                                  ///< Pointer to Multi stats operator
};

CAMX_NAMESPACE_END

#endif // CAMXSTATSPROCESSINGNODE_H
